package cn.vcjf.washcar.common.util.httpUtils;


import com.alibaba.fastjson.JSONObject;
import org.apache.http.*;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.SSLContext;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.*;

public class HttpClientUtils {

    private static Logger logger = LoggerFactory.getLogger(cn.vcjf.washcar.common.util.httpUtils.HttpClientUtils.class);

    private static PoolingHttpClientConnectionManager connectionManager = null;  
    private static HttpClientBuilder httpBuilder = null;  
    private static RequestConfig requestConfig = null;  
    
    private static int MAXCONNECTION = 10;  
    
    private static int DEFAULTMAXCONNECTION = 5;  
    
    private static String IP = "cnivi.com.cn";  
    private static int PORT = 80;  
    
    static {  
        //设置http的状态参数  
        requestConfig = RequestConfig.custom()  
                .setSocketTimeout(5000)  
                .setConnectTimeout(5000)  
                .setConnectionRequestTimeout(5000)  
                .build();  
    
        HttpHost target = new HttpHost(IP, PORT);  
        connectionManager = new PoolingHttpClientConnectionManager();  
        connectionManager.setMaxTotal(MAXCONNECTION);//客户端总并行链接最大数  
        connectionManager.setDefaultMaxPerRoute(DEFAULTMAXCONNECTION);//每个主机的最大并行链接数  
        connectionManager.setMaxPerRoute(new HttpRoute(target), 20);  
        httpBuilder = HttpClients.custom();  
        httpBuilder.setConnectionManager(connectionManager);  
    }  
    
    public static CloseableHttpClient getConnection() {  
        CloseableHttpClient httpClient = httpBuilder.build();  
        return httpClient;  
    }  
    
    
    public static HttpUriRequest getRequestMethod(Map<String, String> map, String url, String method) {  
        List<NameValuePair> params = new ArrayList<NameValuePair>();  
        Set<Map.Entry<String, String>> entrySet = map.entrySet();  
        for (Map.Entry<String, String> e : entrySet) {  
            String name = e.getKey();  
            String value = e.getValue();  
            NameValuePair pair = new BasicNameValuePair(name, value);  
            params.add(pair);  
        }  
        HttpUriRequest reqMethod = null;  
        if ("post".equals(method)) {  
            reqMethod = RequestBuilder.post().setUri(url)  
                    .addParameters(params.toArray(new BasicNameValuePair[params.size()]))  
                    .setConfig(requestConfig).build();  
        } else if ("get".equals(method)) {  
            reqMethod = RequestBuilder.get().setUri(url)  
                    .addParameters(params.toArray(new BasicNameValuePair[params.size()]))  
                    .setConfig(requestConfig).build();  
        }  
        return reqMethod;  
    }

    public static HttpUriRequest getGETMethod(Map<String, String> map,String url){
        return getRequestMethod(map, url, "get");
    }

    public static HttpUriRequest getPOSTMethod(Map<String, String> map,String url){
        return getRequestMethod(map, url, "post");
    }
    public static HttpResponse exeGETMethod(Map<String, String> map,String url) throws IOException {
        HttpClient client = getConnection();
        HttpUriRequest post = getRequestMethod(map, url, "get");
        return client.execute(post);
    }

    public static HttpResponse exePOSTMethod(Map<String, String> map,String url) throws IOException {
        HttpClient client = getConnection();
        HttpUriRequest post = getRequestMethod(map, url, "post");
        return client.execute(post);
    }
    public static boolean isHttpResponseOk(HttpResponse response ){
        if(response==null){
            return false;
        }
        try {
            return response.getStatusLine().getStatusCode() == 200;
        }catch (Exception e){
            return false;
        }
    }

    public static void main(String args[]) throws IOException {
        Map<String, String> map = new HashMap<String, String>();  
        map.put("account", "");  
        map.put("password", "");  
    
        HttpClient client = getConnection();  
        HttpUriRequest post = getRequestMethod(map, "http://cnivi.com.cn/login", "post");  
        HttpResponse response = client.execute(post);  
    
        if (response.getStatusLine().getStatusCode() == 200) {
            HttpEntity entity = response.getEntity();
            String message = EntityUtils.toString(entity, "utf-8");
            logger.debug(message);
        } else {
            logger.error("请求失败");
        }
    }  
	/** 
     * 发送 get请求 
     */   
    public void get() {   
        CloseableHttpClient httpclient = HttpClients.createDefault();   
        try {   
            // 创建httpget.     
            HttpGet httpget = new HttpGet("http://www.baidu.com/");
            logger.debug("executing request " + httpget.getURI());   
            // 执行get请求.     
            CloseableHttpResponse response = httpclient.execute(httpget);
            try {   
                // 获取响应实体     
                HttpEntity entity = response.getEntity();   
                logger.debug("--------------------------------------");   
                // 打印响应状态     
                logger.debug(response.getStatusLine()+"");
                if (entity != null) {   
                    // 打印响应内容长度     
                    logger.debug("Response content length: " + entity.getContentLength());   
                    // 打印响应内容     
                    logger.debug("Response content: " + EntityUtils.toString(entity));   
                }   
                logger.debug("------------------------------------");   
            } finally {   
                response.close();   
            }   
        } catch (ClientProtocolException e) {
            e.printStackTrace();   
        } catch (ParseException e) {
            e.printStackTrace();   
        } catch (IOException e) {
            logger.debug("executing request error");
            e.printStackTrace();   
        } finally {   
            // 关闭连接,释放资源     
            try {   
                httpclient.close();   
            } catch (IOException e) {   
                e.printStackTrace();   
            }   
        }   
    }
	/** 
     * 发送 post请求访问本地应用并根据传递参数不同返回不同结果 
     */   
    public void post() {   
        // 创建默认的httpClient实例.     
        CloseableHttpClient httpclient = HttpClients.createDefault();   
        // 创建httppost     
        HttpPost httppost = new HttpPost("http://localhost:8080/myDemo/Ajax/serivceJ.action");
        // 创建参数队列     
        List<NameValuePair> formparams = new ArrayList<NameValuePair>();   
        formparams.add(new BasicNameValuePair("type", "house"));   

//		StringEntity content =new StringEntity(soapRequestData.toString(), Charset.forName("UTF-8"));// 第二个参数，设置后才会对，内容进行编码
//        content.setContentType("application/soap+xml; charset=UTF-8");
//        content.setContentEncoding("UTF-8");
//        httppost.setEntity(content);
		
        UrlEncodedFormEntity uefEntity;
        try {   
            uefEntity = new UrlEncodedFormEntity(formparams, "UTF-8");   
            httppost.setEntity(uefEntity);   
            logger.debug("executing request " + httppost.getURI());   
            CloseableHttpResponse response = httpclient.execute(httppost);   
            try {   
                HttpEntity entity = response.getEntity();   
                if (entity != null) {   
                    logger.debug("--------------------------------------");   
                    logger.debug("Response content: " + EntityUtils.toString(entity, "UTF-8"));   
                    logger.debug("--------------------------------------");   
                }   
            } finally {   
                response.close();   
            }   
        } catch (ClientProtocolException e) {   
            e.printStackTrace();   
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();   
        } catch (IOException e) {   
            e.printStackTrace();   
        } finally {   
            // 关闭连接,释放资源     
            try {   
                httpclient.close();   
            } catch (IOException e) {   
                e.printStackTrace();   
            }   
        }   
    } 
	/** 
     * post方式提交表单（模拟用户登录请求） 
     */   
    public void postForm() {   
        // 创建默认的httpClient实例.     
        CloseableHttpClient httpclient = HttpClients.createDefault();   
        // 创建httppost     
        HttpPost httppost = new HttpPost("http://localhost:8080/myDemo/Ajax/serivceJ.action");   
        // 创建参数队列     
        List<NameValuePair> formparams = new ArrayList<NameValuePair>();   
        formparams.add(new BasicNameValuePair("username", "admin"));   
        formparams.add(new BasicNameValuePair("password", "123456"));   
        UrlEncodedFormEntity uefEntity;   
        try {   
            uefEntity = new UrlEncodedFormEntity(formparams, "UTF-8");   
            httppost.setEntity(uefEntity);   
            logger.debug("executing request " + httppost.getURI());   
            CloseableHttpResponse response = httpclient.execute(httppost);   
            try {   
                HttpEntity entity = response.getEntity();   
                if (entity != null) {   
                    logger.debug("--------------------------------------");   
                    logger.debug("Response content: " + EntityUtils.toString(entity, "UTF-8"));   
                    logger.debug("--------------------------------------");   
                }   
            } finally {   
                response.close();   
            }   
        } catch (ClientProtocolException e) {   
            e.printStackTrace();   
        } catch (UnsupportedEncodingException e1) {   
            e1.printStackTrace();   
        } catch (IOException e) {   
            e.printStackTrace();   
        } finally {   
            // 关闭连接,释放资源     
            try {   
                httpclient.close();   
            } catch (IOException e) {   
                e.printStackTrace();   
            }   
        }   
    }  
	/** 
     * 上传文件 
     */   
    public void upload() {   
        CloseableHttpClient httpclient = HttpClients.createDefault();   
        try {   
            HttpPost httppost = new HttpPost("http://localhost:8080/myDemo/Ajax/serivceFile.action");   
     
            FileBody bin = new FileBody(new File("F:\\image\\sendpix0.jpg"));
            StringBody comment = new StringBody("A binary file of some kind", ContentType.TEXT_PLAIN);
     
            HttpEntity reqEntity = MultipartEntityBuilder.create().addPart("bin", bin).addPart("comment", comment).build();
     
            httppost.setEntity(reqEntity);   
     
            logger.debug("executing request " + httppost.getRequestLine());   
            CloseableHttpResponse response = httpclient.execute(httppost);   
            try {   
                logger.debug("----------------------------------------");   
                logger.debug(response.getStatusLine()+"");
                HttpEntity resEntity = response.getEntity();   
                if (resEntity != null) {   
                    logger.debug("Response content length: " + resEntity.getContentLength());   
                }   
                EntityUtils.consume(resEntity);   
            } finally {   
                response.close();   
            }   
        } catch (ClientProtocolException e) {   
            e.printStackTrace();   
        } catch (IOException e) {   
            e.printStackTrace();   
        } finally {   
            try {   
                httpclient.close();   
            } catch (IOException e) {   
                e.printStackTrace();   
            }   
        }   
    }  
	/** 
     * HttpClient连接SSL 
     */   
    public void ssl() {   
        CloseableHttpClient httpclient = null;   
        try {   
            KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            FileInputStream instream = new FileInputStream(new File("d:\\tomcat.keystore"));
            try {   
                // 加载keyStore d:\\tomcat.keystore     
                trustStore.load(instream, "123456".toCharArray());   
            } catch (java.security.cert.CertificateException e) {
                e.printStackTrace();
            } finally {
                try {   
                    instream.close();   
                } catch (Exception ignore) {   
                }   
            }   
            // 相信自己的CA和所有自签名的证书   
            SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()).build();
            // 只允许使用TLSv1协议   
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null,
                    SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);   
            httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();   
            // 创建http请求(get方式)   
            HttpGet httpget = new HttpGet("https://localhost:8443/myDemo/Ajax/serivceJ.action");   
            logger.debug("executing request" + httpget.getRequestLine());   
            CloseableHttpResponse response = httpclient.execute(httpget);   
            try {   
                HttpEntity entity = response.getEntity();   
                logger.debug("----------------------------------------");   
                logger.debug(response.getStatusLine()+"");
                if (entity != null) {   
                    logger.debug("Response content length: " + entity.getContentLength());   
                    logger.debug(EntityUtils.toString(entity));   
                    EntityUtils.consume(entity);   
                }   
            } finally {   
                response.close();   
            }   
        } catch (ParseException e) {   
            e.printStackTrace();   
        } catch (IOException e) {   
            e.printStackTrace();   
        } catch (KeyManagementException e) {
            e.printStackTrace();   
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();   
        } catch (KeyStoreException e) {
            e.printStackTrace();   
        } finally {   
            if (httpclient != null) {   
                try {   
                    httpclient.close();   
                } catch (IOException e) {   
                    e.printStackTrace();   
                }   
            }   
        }   
    }
    /**
     * 生成参数
     * @author zhengzihang
     * @param params
     * @return
     */
    public static String buildMapToString(SortedMap<String, String> params) {
        StringBuilder strParam = new StringBuilder();
        for (String key : params.keySet()) {
            strParam.append(key).append("=").append(params.get(key)).append("&");
        }
        return strParam.substring(0,strParam.length()-1).toString();
    }
    /**
     * 获取所有request请求body参数key-value
     *
     * @param request
     * @return
     */
    public static String getRequestBodyStr(HttpServletRequest request) {
        JSONObject object = null;
        StringBuffer resContent = new StringBuffer();
        try (BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream(), "utf-8"))) {
            request.setCharacterEncoding("utf-8");
            String temp = null;
            while ((temp = br.readLine()) != null) {
                resContent.append(temp);
            }
            logger.debug("获取body原始数据:{}", resContent.toString());
            return resContent.toString();

        } catch (Exception e) {
            e.printStackTrace();
            logger.error("获取所有request请求body参数异常:{}",e);
        }
        return "";
    }
}  